package userController

import (
	"fmt"
	"myRbac/models"
	"myRbac/utils"
	"myRbac/utils/jwt"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

type UserController struct{}

// @Summary 用户查询
// @Description 分页查询用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param page query string false "页码"
// @Param pageSize query string false "尺寸"
// @Param username query string false "用户名"
// @Success 200 {object} models.ResultByPage[models.UserSelect] "查询成功"
// @Router /user [get]
// @Security JWT
func (user UserController) QueryUsers(ctx *gin.Context) {
	// 获取分页参数
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10"))
	nameStr := ctx.DefaultQuery("username", "")
	username := "%" + nameStr + "%"
	// 定义承载体
	userList := []models.UserSelect{}
	models.DB.Model(&models.User{}).Where("is_delete!=1 AND username like ?", username).Limit(pageSize).Offset(pageSize * (page - 1)).Find(&userList)
	var total int64
	// 查询条目
	models.DB.Table("users").Where("is_delete!=1 AND username like ?", username).Count(&total)
	// 返回值约束
	result := &models.ResultByPage[models.UserSelect]{
		Msg:      "ok",
		Code:     "200",
		Total:    total,
		Page:     page,
		PageSize: pageSize,
		Result:   userList,
	}
	ctx.JSON(http.StatusOK, result)
}

// @Summary 用户查询
// @Description 根据Id查询用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param id path string true "用户id"
// @Success 200 {object} models.ResultCommon[models.User] "查询成功"
// @Success 401 {object} models.ResultCommon[string] "查询失败"
// @Router /user/{id} [get]
// @Security JWT
func (u UserController) QueryUserById(ctx *gin.Context) {
	user := &models.User{}
	user_id := ctx.Param("id")
	models.DB.Where("id=?", user_id).First(&user)
	if user.Id == 0 {
		ctx.JSON(http.StatusOK, &models.ResultCommon[string]{
			Msg:    "查询失败",
			Code:   "400",
			Result: "",
		})
	} else {
		ctx.JSON(http.StatusOK, &models.ResultCommon[models.User]{
			Msg:    "查询成功",
			Code:   "200",
			Result: *user,
		})
	}
}

// @Summary 新增用户
// @Description 传入json，新增用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param userInfo body models.UserAddParams true "用户信息"
// @Success 200 {object} models.AddResult "新增成功"
// @fail 400 {object} models.ErrorResult "数据错误"
// @fail 401 {object} models.AddResult "新增失败"
// @Router /user [post]
// @Security JWT
func (us UserController) AddUser(ctx *gin.Context) {
	user := &models.UserAddParams{}
	// 绑定json数据
	if err := ctx.ShouldBindJSON(&user); err != nil {
		ctx.JSON(http.StatusOK, &models.ErrorResult{
			Msg:    "数据错误",
			Code:   "400",
			Result: nil,
		})
		fmt.Println(err)
	} else {
		// // 加密密码
		user.Password = utils.Sha256(user.Password)
		// 设置Fid
		token, _ := ctx.Get("token")
		user.Fid = token.(*jwt.MyClaims).User.Id
		newUser := user.User
		result := models.DB.Transaction(func(tx *gorm.DB) error {
			if r1 := tx.Model(&models.User{}).Create(&newUser).Error; r1 != nil {
				return r1
			}
			// 抽离RoleId，插入关系表
			if r2 := tx.Model(&models.UserRole{}).Create(models.UserRole{
				UserId: newUser.Id,
				RoleId: user.RoleId,
			}).Error; r2 != nil {
				return r2
			}
			return nil
		})
		if result != nil {
			ctx.JSON(http.StatusOK, &models.AddResult{
				Msg:    "插入失败",
				Code:   "400",
				Result: 0,
			})
		} else {
			ctx.JSON(http.StatusOK, &models.AddResult{
				Msg:    "插入成功",
				Code:   "200",
				Result: 1,
			})
		}
	}
}

// @Summary 更新用户
// @Description 传入json，更新用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param userInfo body models.User true "用户信息"
// @Success 200 {object} models.UpdateResult[models.User] "更新成功"
// @fail 400 {object} models.ErrorResult "数据错误"
// @fail 401 {object} models.ErrorResult "用户不存在"
// @fail 402 {object} models.AddResult "更新失败"
// @Router /user [put]
// @Security JWT
func (u UserController) UpdateUser(ctx *gin.Context) {
	// 获取提交的用户修改信息
	var user models.UserAddParams
	// 绑定json数据
	if err := ctx.ShouldBindJSON(&user); err != nil {
		ctx.JSON(http.StatusOK, &models.ErrorResult{
			Msg:    "数据绑定失败",
			Code:   "400",
			Result: err,
		})
		return
	}
	// 绑定用户信息
	user_old := &models.User{}
	// 查找用户信息
	models.DB.First(&user_old, user.Id)
	if user_old.Id == 0 {
		ctx.JSON(http.StatusOK, &models.ErrorResult{
			Msg:    "用户不存在",
			Code:   "400",
			Result: nil,
		})
		return
	}
	if user.Password != "" {
		// 加密密码
		user.Password = utils.Sha256(user.Password)
	} else {
		user.Password = user_old.Password
	}
	newUser := user.User

	// 使用事务
	result := models.DB.Transaction(func(tx *gorm.DB) error {
		if r1 := tx.Model(&user_old).Updates(newUser).Error; r1 != nil {
			return r1
		}
		// 抽离RoleId，更新关系表
		if r2 := tx.Model(&models.UserRole{}).Where("user_id=?", newUser.Id).Updates(&models.UserRole{
			UserId: newUser.Id,
			RoleId: user.RoleId,
		}).Error; r2 != nil {
			return r2
		}
		return nil
	})
	if result != nil {
		ctx.JSON(http.StatusOK, &models.ErrorResult{
			Msg:    "更新失败",
			Code:   "400",
			Result: nil,
		})
	} else {
		ctx.JSON(http.StatusOK, &models.UpdateResult[models.User]{
			Msg:    "更新成功",
			Code:   "200",
			Result: newUser,
		})
	}
}

// @Summary 删除
// @Description 传入json，批量删除用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param userIds body models.DeleteParams true "用户id合集"
// @Success 200 {object} models.DeleteResult "更新成功"
// @fail 400 {object} models.ErrorResult "数据错误"
// @fail 401 {object} models.DeleteResult "删除失败"
// @Router /user [delete]
// @Security JWT
func (u UserController) DeleteUser(ctx *gin.Context) {
	// 绑定参数实例
	ids := &models.DeleteParams{}
	// 定义模型实例
	var user models.User
	if err := ctx.ShouldBindJSON(&ids); err != nil {
		ctx.JSON(http.StatusOK, &models.ErrorResult{
			Msg:    "数据绑定失败",
			Code:   "400",
			Result: nil,
		})
	} else {
		// 真的删
		// result := models.DB.Where("id IN (?)", ids.Ids).Delete(&user)
		// 假的删
		result := models.DB.Model(&user).Where("id IN (?)", ids.Ids).Update("is_delete", 1)
		if result.RowsAffected != 0 {
			ctx.JSON(http.StatusOK, &models.DeleteResult{
				Msg:    "删除成功",
				Code:   "200",
				Result: ids.Ids,
			})
		} else {
			ctx.JSON(http.StatusOK, &models.DeleteResult{
				Msg:    "删除失败",
				Code:   "400",
				Result: []int{0},
			})
		}
	}
}

// @Summary 用户查询
// @Description 只查询自己子集的用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Success 200 {object} models.ResultCommon[[]models.UserSelect] "查询成功"
// @Router /user/subset [get]
// @Security JWT
func (u UserController) QueryUserSubset(ctx *gin.Context) {
	// 获取id
	token, _ := ctx.Get("token")
	// 断言成那个类型
	id := &token.(*jwt.MyClaims).User.Id
	// 声明承载体
	userList := []models.UserSelect{}
	models.DB.Model(&models.User{}).Where("fid=?", id).Find(&userList)
	ctx.JSON(http.StatusOK, &models.ResultCommon[[]models.UserSelect]{
		Msg:    "查询成功",
		Code:   "200",
		Result: userList,
	})
}
